#ifndef PATH_H_
#define PATH_H_

//@Include: bounce_path.h
//@Include: falling_path.h
//@Include: puzzle_path.h

// INCLUDES //
#include "SDL/SDL.h"
#include "area.h"
#include <vector.h>
//////////////

/**
* A path calculates an object's location based on input and time. The base path keeps
* the object stationary.
* 
* @author dfoelber
**/
class Path
{
public:
	/**
	* Various events that could happen to a path.
	**/
	enum PuzzleEvent
	{
		ROTATION_COLLISION = 0
	};
	
	/**
	* The sides of collisions
	**/
	enum Side
	{
		SIDE_NONE = 0,
		SIDE_LEFT = 1,
		SIDE_RIGHT = 2,
		SIDE_TOP = 4,
		SIDE_BOTTOM = 8
	};	
	
	/**
	* Direction of the current key strokes
	**/
	enum Direction
	{
		DIRECTION_NONE = 0,
		DIRECTION_UP,
		DIRECTION_DOWN,
		DIRECTION_LEFT,
		DIRECTION_RIGHT
	};
	
public:
	/**
	* Default constructor.
	**/
	Path();
	
	/**
	* Deconstructor
	**/
	virtual ~Path();
	
	/**
	* Lets the path know that time has passed and to move accordingly.
	* 
	* @param ms The time passed since last called
	**/
	virtual void TimePassed( int ms );

	/**
	* Input that can be used by the path.
	* 
	* @param event The event
	* @return If the event was consumed
	**/
	virtual bool Input( SDL_Event event );
	
	/**
	* Check if this path collided with another path.
	* 
	* @param other The other path.
	**/
	virtual void CheckCollision( Path* other );
	
	/**
	* Sets the position of the path.
	* 
	* @param x The new X coordinate
	* @param y The new Y coordinate
	**/
	virtual void SetPosition( int x, int y );
	
	/**
	* Sets the size of the path.
	* 
	* @param width The new width
	* @param height The new height
	**/
	void SetSize( int width, int height );
	
	/**
	* Gets the width of the path.
	* 
	* @return The current width
	**/
	int GetWidth() const;
	
	/**
	* Gets the height of the path.
	* 
	* @return The current height
	**/
	int GetHeight() const;
	
	/**
	* Gets the X coordinate of the path.
	* 
	* @return The current X coordinate
	**/
	int GetX() const;
	
	/**
	* Gets the Y coordinate of the path.
	* 
	* @return The current Y coordinate
	**/
	int GetY() const;
	
	/**
	* Gets the X velocity of the path.
	* 
	* @return The current X velocity
	**/
	virtual double GetXVel() const;
	
	/**
	* Gets the Y velocity of the path.
	* 
	* @return The current Y velocity
	**/
	virtual double GetYVel() const;
	
	/**
	* Gets the planned X distance of the path.
	* 
	* @return The currently planned X distance
	**/
	double GetXDistance() const;
	
	/**
	* Gets the planned Y distance of the path.
	* 
	* @return The currently planned Y distance
	**/
	double GetYDistance() const;
	
	/**
	* Sets the key direction.
	* 
	* @param direction The key direction to set
	**/
	void SetKeyDirection( Direction direction );
	
	/**
	* Gets the key direction.
	* 
	* @return The current key direction
	**/
	Direction GetKeyDirection() const;
	
	/**
	* Adds another path to this path's association list. Transfers ownership to the path.
	* 
	* @param path the path to add
	**/	
	void AddAssociation( Path* path );
	
	/**
	* Removes a specific path to this path's association list.
	* 
	* @param path the path to remove
	**/	
	void RemoveAssociation( Path* path );
	
	/**
	* Removes all paths from this path's association list.
	**/	
	void RemoveAllAssociations();
	
	/**
	* Accessor to the path's association list.
	* 
	* @return the association list
	**/	
	const vector<Path*>& GetAssociations();
	
	/**
	* Notifies the path that an event has occurred.
	* 
	* @param event The event that occurred
	**/
	virtual void PuzzleEventOccurred( PuzzleEvent event );
	
	/**
	* Sets if the path is rotating.
	* 
	* @param rotate If the path is rotating
	**/
	void SetRotating( bool rotate );
	
	/**
	* Advances the path, applying its x and y distances.
	**/
	virtual void Advance();
	
	/**
	* Moves the path by the distance supplied.
	* 
	* @param x The X distance to move the path
	* @param x The Y distance to move the path
	**/
	void MoveDistance(double x, double y);
	
	/**
	* Gets if the path is still moving.
	* 
	* @return If the path is moving
	**/
	virtual bool IsMoving();
	
	/**
	* Sets the current AI command.
	* 
	* @param command The new command
	**/
	void SetAICommand( int command ) { aiCommand = command; }
	
	/**
	* Gets the current AI command.
	* 
	* @return The current AI command
	**/
	int GetAICommand() { return aiCommand; }
	
	/**
	* Sets the rotation.
	* 
	* @param rotation The new rotation (in degrees)
	**/
	void SetRotation( int rotation ) { this->rotation = rotation; }
	
	/**
	* Gets the current rotation.
	* 
	* @return The current rotation.
	**/
	int GetRotation() { return rotation; }
	
	/**
	* Sets the area with a new area.
	* 
	* @param area The new area.
	**/
	void SetArea(Area* area);
	
	/**
	* Gets the current area.
	* 
	* @return The area.
	**/
	Area* GetArea() { return area; }
	
protected:
	/// If the path is rotating.
	double			rotating;
	/// The X coordinate of the path
	double 			x;
	/// The Y coordinate of the path
	double			y;
	/// The X velocity
	double			xVel;
	/// The Y velocity
	double			yVel;
	/// The width of the path
	int 			width;
	/// The height of the path
	int				height;
	/// The X distance
	double			xDistance;
	/// The Y distance
	double			yDistance;
	/// The current key direction
	Direction 		keyDir;
	/// The path's associations
	vector<Path*>	associations;
	/// The AI command
	int				aiCommand;
	/// The path's rotation
	int				rotation;
	/// The path's area
	Area*			area;
};

#endif /*PATH_H_*/
